package com.qianfeng.smartdevice.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qianfeng.smartdevice.dto.UserDto;
import com.qianfeng.smartdevice.enums.CheckType;
import com.qianfeng.smartdevice.enums.LoginResutEnum;
import com.qianfeng.smartdevice.events.MyLoginEvent;
import com.qianfeng.smartdevice.exceptions.AddDataErrorException;
import com.qianfeng.smartdevice.exceptions.MyErrorCode;
import com.qianfeng.smartdevice.exceptions.QueryDataErrorException;
import com.qianfeng.smartdevice.mapper.SysUserInfoMapper;
import com.qianfeng.smartdevice.pojo.SysUserInfo;
import com.qianfeng.smartdevice.service.SysUserInfoService;
import com.qianfeng.smartdevice.utils.MD5Utils;
import com.qianfeng.smartdevice.utils.MyStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * @time: 2022-03-14 17:22
 */

@Service
@Transactional
public class SysUserInfoServiceImpl implements SysUserInfoService {

    private ApplicationContext applicationContext;

    @Autowired
    public void setContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    Logger logger = LoggerFactory.getLogger(SysUserInfoServiceImpl.class);

    private SysUserInfoMapper sysUserInfoMapper;

    @Autowired
    public void setSysUserInfoMapper(SysUserInfoMapper sysUserInfoMapper) {
        this.sysUserInfoMapper = sysUserInfoMapper;
    }

    @Override
    public SysUserInfo login(UserDto userDto) {
        //用户传递的账号和密码是我不能为空的
        Assert.isTrue(StringUtils.hasText(userDto.getUsername())&&StringUtils.hasText(userDto.getPassword()),()->{
            throw new QueryDataErrorException("用户名密码为空",MyErrorCode.DATA_NULL);
        });
        //根据用户的名字查询用户数据
        SysUserInfo userInfo = sysUserInfoMapper.findByUsername(userDto.getUsername());
        //查询到了，就获取到盐
        Assert.notNull(userInfo,()->{
            throw new QueryDataErrorException("用户名或密码错误",MyErrorCode.USERNAME_PASSWORD_ERROR);
        });
        //用盐将传递过来的密码转成散列值
        String pwdSalt = userInfo.getPwdSalt();
        String pwdMD5 = MD5Utils.getMd5(userDto.getPassword(), pwdSalt, 2048);
        //然后在比较
        Assert.isTrue(pwdMD5.equalsIgnoreCase(userInfo.getPassword()),()->{
            applicationContext.publishEvent(new MyLoginEvent(LoginResultEnum.FAIL,userDto.getUsername()));
            throw new QueryDataErrorException("用户名或密码错误",MyErrorCode.USERNAME_PASSWORD_ERROR);
        });
        userInfo.setPwdSalt(null);//防止将盐泄露到前端
        userInfo.setPassword(null);//防止将面膜泄露到前端
        //记录日志
        applicationContext.publishEvent(new MyLoginEvent(LoginResultEnum.SUCCESS,userDto.getUsername()));
        return userInfo;
    }

    @Override
    public SysUserInfo findById(Long userId) {
        return sysUserInfoMapper.findById(userId);
    }

    @Override
    public PageInfo<SysUserInfo> findAll(int pageSize, int pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<SysUserInfo> all = sysUserInfoMapper.findAll();
        PageInfo<SysUserInfo> pageInfo=new PageInfo<>(all);
        return pageInfo;
    }


    @Override
    public void addUser(SysUserInfo sysUserInfo) {
        //数据校验，应该传递的数据必须传递，数据是不是空的，需要什么数据，只有对象自己知道。
        Assert.isTrue(!sysUserInfo.isEmpty(CheckType.ADD),()->{
            throw new AddDataErrorException("数据不能为空", MyErrorCode.DATA_NULL);
        });
        //数据格式校验
        //校验手机号
        Assert.isTrue(MyStringUtils.check(sysUserInfo.getPhone(),MyStringUtils.mobileRegex),()->{
            throw new AddDataErrorException("非法的手机号，请想清楚在填写手机号",MyErrorCode.PHONE_REG_NOT_MACTH);
        });
        //校验邮箱
        Assert.isTrue(MyStringUtils.check(sysUserInfo.getEmail(),MyStringUtils.emailRegex),()->{
            throw new AddDataErrorException("不正确的邮箱格式，请仔细填写邮箱",MyErrorCode.MAIL_REG_NOT_MACTH);
        });

        //校验唯一数据
        //用户名 手机号和邮箱必须检查
        //按照用户名查询一下
        SysUserInfo info = sysUserInfoMapper.findByUsername(sysUserInfo.getUsername());
        Assert.isNull(info,()->{
            throw new AddDataErrorException("用户名已经存在,请重新思考一下下",MyErrorCode.USER_ALREADY_EXIST);
        });
        //按照手机号检查
        info= sysUserInfoMapper.findByPhone(sysUserInfo.getPhone());
        Assert.isNull(info,()->{
            throw new AddDataErrorException("手机号已注册，请换一个手机号",MyErrorCode.PHONE_ALREADY_EXIST);
        });
        //按照邮箱检查
        info= sysUserInfoMapper.findByEmail(sysUserInfo.getEmail());
        Assert.isNull(info,()->{
            throw new AddDataErrorException("邮箱已存在，请重新想一个",MyErrorCode.EMAIL_ALREADY_EXIST);
        });
        //生成盐
        String salt = MD5Utils.getRandomString(10);
        sysUserInfo.setPwdSalt(salt);
        //生成密码
        String passwordMD5 = MD5Utils.getMd5(sysUserInfo.getPassword(), salt, 2048);//计算密码的MD5值
        sysUserInfo.setPassword(passwordMD5);//将密码替换为MD5值
        //设置默认数据
        sysUserInfo.setCreateTime(new Date());
        //检查当前登录的用户，如果是管理员的信息，如果没有就是用户自己注册的
        sysUserInfo.setCreateBy(sysUserInfo.getUsername());
        sysUserInfo.setRemark("普通用户");
        //保存到数据库
        sysUserInfoMapper.addUser(sysUserInfo);
        logger.error("添加数据成功");
    }
}